<?php
/*
Plugin Name: CAS Authentication
Plugin URI: http://code.google.com/p/yourls-cas-plugin/
Description: Add support for CAS (Central Auth Service).
Version: 1.0
Author: nicwaller
Author URI: http://code.google.com/u/101717938102134699062/
*/

// No direct call
if( !defined( 'YOURLS_ABSPATH' ) ) die();

// returns true if the phpCAS environment is set up right
function cas_environment_check() {
	$required_params = array(
		'PHPCAS_PATH', // path to phpCAS loader file (CAS.php)
		'PHPCAS_HOST', // full hostname of your CAS server
		'PHPCAS_CONTEXT', // context of the CAS server (webapp subdirectory)
		'PHPCAS_CERTCHAIN_PATH', // path to a .pem file containing 1 or more CA certs
	);

	foreach ($required_params as $pname) {
		if ( !defined( $pname ) ) {
			$message = 'Missing defined parameter '.$pname.' in plugin '. $thisplugname;
			error_log($message);
			return false;
		}
	}
	
	if ( !defined( 'PHPCAS_PORT' ) )
		define( 'PHPCAS_PORT', 443 );

	if ( !defined( 'PHPCAS_HIJACK_LOGIN' ) )
		define( 'PHPCAS_HIJACK_LOGIN', true );

	return true;
}



yourls_add_action( 'redirect_keyword_not_found', 'cas_page_hook' );

function cas_page_hook( $args ) {
	$keyword = $args[0];

	if ( $keyword == 'caslogin' ) {
		if ( !cas_environment_check() ) {
			die( 'Invalid configuration for phpCAS. Check PHP error log.' );
		}

		require_once PHPCAS_PATH; // /*$phpcas_path .*/ 'phpcas/CAS.php';

		phpCAS::setDebug();
		phpCAS::client(CAS_VERSION_2_0, PHPCAS_HOST, PHPCAS_PORT, PHPCAS_CONTEXT);
		phpCAS::setCasServerCACert(PHPCAS_CERTCHAIN_PATH);
		phpCAS::forceAuthentication();
		// then set up external-auth cookie
		// or just use PHP session management
		session_start();
		$_SESSION['CAS_AUTH_USER'] = phpCAS::getUser();
		header('Location: ' . yourls_admin_url( 'index.php' ) );
		die('');
	}
}



yourls_add_action( 'logout', 'cas_logout_hook' );

function cas_logout_hook( $args ) {
	unset($_SESSION['CAS_USER_AUTH']);
	setcookie('PHPSESSID', '', 0, '/');

	// to enable single sign-out, also teardown the CAS session
	// phpCAS::logout();
}



yourls_add_filter( 'is_valid_user', 'cas_is_valid_user' );

// returns true/false
function cas_is_valid_user( $value ) {
	// since logout is handled in the cookie checking, we also must handled it here
	// otherwise, the user sees the admin page again once after logging out
        if ( isset( $_GET['action'] ) && $_GET['action'] == 'logout' ) {
		yourls_do_action( 'logout' );
                yourls_store_cookie( null );
                
		// normally a logout would just show the login page
		// but we don't want to show the login page, really.
		//return 'Logged out successfully';
		header( 'Location: ' . yourls_site_url() );
		die();
	}

	session_start();
	if ( isset( $_SESSION['CAS_AUTH_USER'] ) ) {
		yourls_set_user( $_SESSION['CAS_AUTH_USER'] );
		return true;
	} else {
		// If auth is required, and if auth fails, then YOURLS will always
		// display the login screen. We want to hijack that.
		// at this point, we already know that no CAS external auth is available
		if ( PHPCAS_HIJACK_LOGIN ) {
			header('Location: ' . yourls_site_url() . '/caslogin' );
			die();
		}
	}
	
	return $value;
}

